package com.mls.guardian.appst.chain.excutor;

import com.mls.guardian.appst.chain.TaskExecutor;
import com.mls.guardian.appst.chain.TaskInvoker;
import com.mls.guardian.appst.chain.TaskResult;
import com.mls.guardian.appst.shell.ShellScriptExecutorFuture;
import com.mls.guardian.common.FileUtil;
import com.mls.guardian.dataobj.ModuleMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * Created by 2014-400 on 2015-10-26.
 */
public class RestartJarExcutor implements TaskExecutor {
    private static final Logger log = LoggerFactory.getLogger(RestartJarExcutor.class);

    @Override
    public TaskResult exec(TaskInvoker invoker) {
       
        //优先取项目配置,如果没有取config.properties配置
        String springActive = invoker.getProject().getSpringActive();
        if (springActive == null || springActive.trim().length() == 0) {
            springActive = invoker.getConfig().getSpringActive();
        }

        TaskResult result = null;
        try {
            log.info("----开始restart jar----");
            for (ModuleMessage item : invoker.getModuleList()) {
                log.info("----restart jar[{}]----", item.getModuleName());
                String startFile = invoker.getConfig().getMoveDest() + File.separator + invoker.getProject().getProjectName() + File.separator + item.getModuleName() + ".jar";
                String bashFilePath = System.getProperty("user.home") + File.separator + "guardianConfig" + File.separator + "guardian_" + System.currentTimeMillis() + ".sh";

                //判断jar包是否已经生成
                if (false == Files.exists(Paths.get(startFile))) {
                    throw new Exception("未找到对应文件:" + startFile);
                }

                //jvm参数
                String jvmArgs = "";
                int index = invoker.getProject().getJarModuleList().indexOf(item.getModuleName());
                if (index > -1 && index < invoker.getProject().getJvmArgs().size()) {
                    jvmArgs = invoker.getProject().getJvmArgs().get(index);
                }


                FileUtil.append(bashFilePath, "pid=$(ps -ef|grep java |grep " + item.getModuleName() + ".jar |awk '{print $2}')");
                FileUtil.append(bashFilePath, "echo killing $pid");
                FileUtil.append(bashFilePath, "OLD_IFS=\"$IFS\"");
                FileUtil.append(bashFilePath, "IFS=\" \"");
                FileUtil.append(bashFilePath, "arr=($pid)");
                FileUtil.append(bashFilePath, "IFS=\"$OLD_IFS\"");
                FileUtil.append(bashFilePath, "for s in ${arr[@]}");
                FileUtil.append(bashFilePath, "do");
                FileUtil.append(bashFilePath, "echo killed $s");
                FileUtil.append(bashFilePath, "kill -9 $s");
                FileUtil.append(bashFilePath, "done");
                FileUtil.append(bashFilePath, "echo kill pid finished");
                FileUtil.append(bashFilePath, "nohup java -Dspring.profiles.active=" + springActive + " " + jvmArgs + " -jar " + startFile + " > /dev/null 2>&1 &");
                FileUtil.append(bashFilePath, "sleep 1");
                FileUtil.append(bashFilePath, "echo done");

                result = new ShellScriptExecutorFuture("sh " + bashFilePath).execute();

                //暂停一下
                int sleepSecond = invoker.getConfig().getRestartSleep();
                if (sleepSecond <= 0) {
                    sleepSecond = 10;
                }
                try {
                    Thread.sleep(sleepSecond * 1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //删除临时文件
                try {
                    Files.delete(Paths.get(bashFilePath));
                } catch (IOException e) {
                    e.printStackTrace();
                }

                //一旦报错,停止循环
                if (result.isSuc() == false) {
                    break;
                }
            }//end-for

            if (result.isSuc() == true) {
                return invoker.invoke();
            }
        } catch (Exception e) {
            result = new TaskResult();
            result.setSuc(false);
            result.setError(e.getMessage());

            e.printStackTrace();
        } finally {
            log.info("----结束restart jar[{}]----", result.isSuc());
        }

        return result;
    }
}
